package com.piece.core.framework.util.file;

import com.piece.core.framework.support.convert.Convert;
import com.piece.core.framework.util.string.StringUtil;
import org.apache.commons.io.IOUtils;
import java.io.*;

public class IoUtil extends IOUtils {

    public static ByteArrayOutputStream read(InputStream in, boolean isClose) throws IOException {
        ByteArrayOutputStream bos;
        if (in instanceof FileInputStream) {
            try {
                bos = new ByteArrayOutputStream(in.available());
            } catch (IOException e) {
                throw new IOException(e);
            }
        } else {
            bos = new ByteArrayOutputStream();
        }

        try {
            copy(in, bos);
        } finally {
            if (isClose) {
                close(in);
            }

        }

        return bos;
    }

    public static byte[] readBytes(InputStream in) throws IOException {
        return readBytes(in, true);
    }

    public static byte[] readBytes(InputStream in, boolean isClose) throws IOException {
        if (!(in instanceof FileInputStream)) {
            return read(in, isClose).toByteArray();
        } else {
            byte[] result;
            try {
                int available = in.available();
                result = new byte[available];
                int readLength = in.read(result);
                if (readLength != available) {
                    throw new IOException(StringUtil.format("File length is [{}] but read [{}]!", new Object[]{available, readLength}));
                }
            } catch (IOException e) {
                throw new IOException(e);
            } finally {
                if (isClose) {
                    close(in);
                }
            }

            return result;
        }
    }

    public static byte[] readBytes(InputStream in, int length) throws IOException {
        if (null == in) {
            return null;
        } else if (length <= 0) {
            return new byte[0];
        } else {
            byte[] b = new byte[length];

            int readLength;
            try {
                readLength = in.read(b);
            } catch (IOException var5) {
                throw new IOException(var5);
            }

            if (readLength > 0 && readLength < length) {
                byte[] b2 = new byte[readLength];
                System.arraycopy(b, 0, b2, 0, readLength);
                return b2;
            } else {
                return b;
            }
        }
    }

    public static String readString(InputStream in, boolean isClose) throws IOException {
        return StringUtil.string(read(in, isClose));
    }

    public static void write(OutputStream out, byte[] content, boolean flush, boolean isCloseOut) throws IOException {
        try {
            out.write(content);
            if (flush) {
                out.flush();
            }
        } catch (IOException e) {
            throw new IOException(e);
        } finally {
            if (isCloseOut) {
                close(out);
            }
        }
    }

    public static void write(OutputStream out, boolean isCloseOut, Object... contents) throws IOException {
        OutputStreamWriter osw = null;
        try {
            osw = new OutputStreamWriter(out);
            Object[] var5 = contents;
            int var6 = contents.length;

            for(int var7 = 0; var7 < var6; ++var7) {
                Object content = var5[var7];
                if (content != null) {
                    osw.write(Convert.toStr(content, ""));
                }
            }

            osw.flush();
        } catch (IOException e) {
            throw new IOException(e);
        } finally {
            if (isCloseOut) {
                close(osw);
            }
        }
    }

    public static long copy(InputStream is, OutputStream os, int bufferSize, long count, boolean isCloseOut) throws IOException {
        long total = 0L;
        long numToRead = count > 0L ? count : 9223372036854775807L;
        int len = (int)Math.min(bufferSize, numToRead);
        byte[] buffer = new byte[len];

        try {
            while(numToRead > 0L) {
                int read = is.read(buffer, 0, len);
                if (read < 0) {
                    break;
                }

                os.write(buffer, 0, read);
                numToRead -= read;
                total += read;
            }

            return total;
        } catch (IOException e) {
            throw new IOException(e);
        } finally {
            if (isCloseOut) {
                close(os);
                close(is);
            }
        }
    }

    public static void close(Closeable closeable) {
        if (null != closeable) {
            try {
                closeable.close();
                closeable = null;
            } catch (Exception e) {
            }
        }
    }
}
